﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Windows.Automation;
using System.Windows.Automation.Peers;
using System.Windows.Automation.Provider;
using System.Windows.Art;

namespace System.Windows.Elements
{
    public class ColorPicker : FrameworkElement
    {
        private static readonly DependencyPropertyKey AccumulatorKey;
        private static readonly DependencyProperty AccumulatorProperty, InternalColorProperty;

        public static readonly DependencyProperty ColorProperty;
        public static readonly RoutedEvent ColorChangedEvent = EventManager.RegisterRoutedEvent("ColorChanged", RoutingStrategy.Bubble, typeof(RoutedPropertyChangedEventHandler<IColor>), typeof(ColorPicker));

        public event RoutedPropertyChangedEventHandler<IColor> ColorChanged
        {
            add { this.AddHandler(ColorPicker.ColorChangedEvent, value); }
            remove { this.RemoveHandler(ColorPicker.ColorChangedEvent, value); }
        }

        protected virtual void OnColorChanged(IColor oldValue, IColor newValue)
        {
            RoutedPropertyChangedEventArgs<IColor> args = new RoutedPropertyChangedEventArgs<IColor>(oldValue, newValue);
            args.RoutedEvent = ColorPicker.ColorChangedEvent;
            this.RaiseEvent(args);
        }

        static ColorPicker()
        {
            DefaultStyleKeyProperty.OverrideMetadata(typeof(ColorPicker), new FrameworkPropertyMetadata(typeof(ColorPicker)));

            var defaultColor = Colors.Black.ToRgb();
            ColorPicker.AccumulatorKey = DependencyProperty.RegisterReadOnly("Accumulator", typeof(ColorAccumulator), typeof(ColorPicker), new FrameworkPropertyMetadata(new ColorAccumulator(defaultColor)));
            ColorPicker.AccumulatorProperty = ColorPicker.AccumulatorKey.DependencyProperty;

            ColorPicker.ColorProperty = DependencyProperty.Register("Color", typeof(IColor), typeof(ColorPicker), new FrameworkPropertyMetadata(defaultColor, new PropertyChangedCallback(ColorPicker.OnColorChanged)));
            ColorPicker.InternalColorProperty = DependencyProperty.Register("InternalColor", typeof(IColor), typeof(ColorPicker), new FrameworkPropertyMetadata(defaultColor, new PropertyChangedCallback(ColorPicker.OnInternalColorChanged)));
        }

        public ColorPicker()
        {
            this.InitializeBindings();
        }

        //protected override AutomationPeer OnCreateAutomationPeer()
        //{
        //    return new ColorPickerAutomationPeer(this);
        //}

        void InitializeBindings()
        {
            Binding binding;

            binding = new Binding("Color");
            binding.Source = this.Accumulator;
            binding.Mode = BindingMode.TwoWay;
            this.SetBinding(ColorPicker.InternalColorProperty, binding);
        }

        static void OnColorChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            var picker = (ColorPicker)d;
            var newValue = (IColor)e.NewValue;
            picker.SetValue(ColorPicker.InternalColorProperty, newValue);
            picker.OnColorChanged((IColor)e.OldValue, newValue);

            //var peer = (ColorPickerAutomationPeer)UIElementAutomationPeer.FromElement(picker);
            //if (peer != null) peer.RaiseValueChangedAutomationEvent(e.OldValue, e.NewValue);
        }

        static void OnInternalColorChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            var picker = (ColorPicker)d;
            var newValue = (IColor)e.NewValue;
            picker.SetValue(ColorPicker.ColorProperty, newValue);
        }

        public ColorAccumulator Accumulator
        {
            get { return (ColorAccumulator)this.GetValue(ColorPicker.AccumulatorProperty); }
        }

        public IColor Color
        {
            get { return (IColor)this.GetValue(ColorPicker.ColorProperty); }
            set { this.SetValue(ColorPicker.ColorProperty, value); }
        }
    }

    //public class ColorPickerAutomationPeer : FrameworkElementAutomationPeer, IValueProvider
    //{
    //    public ColorPickerAutomationPeer(ColorPicker picker)
    //        : base(picker)
    //    {
    //    }

    //    protected override String GetClassNameCore()
    //    {
    //        return "ColorPicker";
    //    }

    //    protected override AutomationControlType GetAutomationControlTypeCore()
    //    {
    //        return AutomationControlType.Custom;
    //    }

    //    public override Object GetPattern(PatternInterface patternInterface)
    //    {
    //        if (patternInterface == PatternInterface.Value) return this;
    //        else return base.GetPattern(patternInterface);
    //    }

    //    internal void RaiseValueChangedAutomationEvent(Color oldColor, Color newColor)
    //    {
    //        base.RaisePropertyChangedEvent(ValuePatternIdentifiers.ValueProperty, oldColor.ToString(), newColor.ToString());
    //    }

    //    public Boolean IsReadOnly
    //    {
    //        get { return true; }
    //    }

    //    public void SetValue(String value)
    //    {
    //        throw new NotSupportedException();
    //    }

    //    public String Value
    //    {
    //        get { return ((ColorPicker)base.Owner).Color.ToString(); }
    //    }
    //}
}
